週刊Automatineマガジン 1.AutomatineでのCoroutine
概要
毎号集めても何もない。ドキュメント作る時の備忘録。
今回は、AutomatineでのCoroutineの指針と、Coroutineで扱うパラメータ解説。
Coroutineの指針
Coroutineを超えてパラメータを扱いたい、、という時にはInitialTypeParamのパラメータを使おう
1.ロックオン
2.ロックしてあるやつを殴りに行く
こういう時には、InitialTypeParam自体や、そのプロパティ、値に「ロックした敵」というパラメータを持つといい。
実行中の各Coroutineでインスタンスを共有できるので、ロックした敵があったらそのIdを使って~みたいな書き方ができる。
Autoを超えてパラメータを扱いたい、、という時にも、contextのパラメータを使おう
初期化時に渡すと楽。
var context = new Context();
auto = new Something<Context, Other>(frame, context);
Coroutineは部品のように細かく分けて作ってもいいけど、大雑把に作って後で割るのもOK
e.g.
一番近い敵の方を向く
敵まで歩いていく
最初はゴチャッと作っちゃっても問題ない。
e.g.
一番近い敵の方に向いてそのまま歩いていって殴る
ただし、名前とコメントをつけるようにしよう。
Coroutineの役割の分解は、コードがあんまり分散してないので、あとで簡単にできる。
まずは動くものを作って、そのあと切り分けるのがカンタン。
Coroutineで扱うパラメータ解説
Coroutineの初期値とパラメータについて
Timeline上に複数のTackを置いた場合、そのTackについているCoroutineが順に実行されるわけだが。
実行されるCoroutineには、次の2つのパラメータが入る。
1.initialParam、すべてのCoroutineから参照/設定ができるパラメータ
2.updateParam、auto.Updateの度に更新されるパラメータ
1.initialParam、すべてのCoroutineから参照/設定ができるパラメータ
new時にInitialParamTypeで型指定、initialParamとして渡せる値は、
・Autoのnewの時に、全Coroutineへと渡るパラメータになる
・全Coroutineからの変更が可能
という特性を持っている。
具体例として、次のようなAutoを初期化するコードがあると、
auto = new Auto<string, int>(frame, “初期値”);
InitialParamType には string型がセットされ、コンストラクタの第二引数 InitialTypeのパラメータにもstring型の値が入っている。
こうすると、このAutoのすべてのTimelineのすべてのTackに対して、Coroutine動作時に渡されるパラメータとして “初期値” という文字列が入る。
public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {
public IEnumerator TheCoroutine1 (InitialParamType initialParam) {
// ここで、initialParamの型は string になっている。 キャストして取り出すことができる。
var str = initialParam as string;
// この値は、このTimelineにセットされているどのCoroutineでも、そのTimeliineが所属するAutoを初期化した値になっている。
if (str == “初期値”) {
// true.
}
yield return null;
}
}
もし、InitialParamに自分で定義したクラスのインスタンスを入れた場合、そのインスタンスはそのAuto内のすべてのCoroutineに引き継がれる。
次のような[パラメータのパッケージ]をクラスとして定義してInitialTypeParamとして使う場合、
public class Params {
public string message;
}
auto = new Auto<Params, int>(frame, new Params());
ここで new Params() したインスタンスが、そのAutoの中のすべてのCoroutineからアクセス可能になる。
どこかのCoroutineで変更を加えると、その変更は他のCoroutineからも参照、変更できる。
次のCoroutine TheCoroutine2で、Paramsインスタンスのmessageという変数に”hello!!”という文字列をセットすると、
public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {
public IEnumerator TheCoroutine2 (InitialParamType initialParam) {
var params = initialParam as Params;
params.message = “hello!!”;
yield return null;
}
}
その後に実行されるCoroutineからは、その変更が把握できる。
public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {
public IEnumerator TheCoroutine3 (InitialParamType initialParam) {
var params = initialParam as Params;
if (params.message == “hello!!”;) {
// true.
}
yield return null;
}
}
こんな感じで、initialParamには次のような性質がある。
・Autoのnewの時に、全Coroutineへと渡るパラメータになる
・全Coroutineからの参照、変更が可能
2.updateParam、auto.Updateの度に更新されるパラメータ
Coroutineには、this.updateParam, this.frame などのパラメータが定義されている。
これらの値はAutoのアップデートを行うタイミングでセットすることができる。
例えばこんなクラスを用意し、
public class Params {
public string message;
}
Autoを次のように初期化した場合、
auto = new Auto<string, Params>(frame, “初期化”);
UpdateParamTypeには、Params型を指定してあり、
この後に実行するauto.Updateで、第二引数としてParams型のインスタンスを実行中のCoroutineへと渡すことができる。
var updateParam = new Params();
updateParam.message = “World!” + frame;
auto.Update(frame, updateParam)
frame++;
このUpdateでは、実行開始のタイミング or 実行中のすべてのCoroutineへと、updateParamが入力される。
先ほどのUpdateを実行すると、Coroutineの中のパラメータはこんな感じになる。
public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {
public IEnumerator TheCoroutine4 (InitialParamType initialParam) {
var updateParams = this.updateParam as Params;
if (updateParams.message.StartsWith(“World!”)) {
// true.
}
yield return null;
}
}
また、複数回実行できるようなCoroutineの場合、毎回実行されるたびにupdateParamが更新される。
public partial class RoutineContexts<InitialParamType, UpdateParamType> : RoutineBase<InitialParamType, UpdateParamType> {
public IEnumerator TheCoroutine4 (InitialParamType initialParam) {
while (true) {
var updateParams = this.updateParam as Params;
Debug.Log(“updateParams.message:” + updateParams.message); // updateParams.message:World!フレーム数 (フレーム数部分は変動
yield return null;
}
}
}
ざっくり書くと、Updateを行うと、実行状態になった全Coroutineにその値がセットされ実行される。
auto.Update(frame, obj) ――> CoroutineA {this.updateParamにはobjが入っている}
――> CoroutineB {this.updateParamにはobjが入っている}
――> CoroutineC {this.updateParamにはobjが入っている}
Coroutine中の定義済みの値には、次のものがある。
・int frame
Update関数で入力したframeが入る。
・UpdateParamType updateParam
Update関数で入力したupdateParamが入る。
・loadCount
このCoroutineの実行回数が入っている。初回0。
まとめ
Coroutineに入ってくるパラメータ、
・一つのインスタンスをひき回せるInitialParamType
・毎フレーム更新されるUpdateParamType
の2つがある。
必要に合わせて使うといいと思う。